<template>
	<n-tabs v-if='commonStore.getDynamicAsyncCustomComponentIsReady'
			v-bind='tabConfig' class='tabs-container'
			v-model:value='tabsStore.currentActivatedTab as string'>
		<template v-for='item of tabsStore.tabs'>
			<n-tab-pane
				:closable='homeCode !== item.menuCode'
				:display-directive='displayMode(item)' :name='item.menuCode'
				:tab='renderLabel(item)'
				:tab-props='{onContextmenu(event: MouseEvent) {onRightClick(event, item)}}'>
				<Suspense>
					<template v-slot>
						<component v-if='item.params'
								   :key='`n-tabs_n-tab-pane_component_${item.key}_component`'
								   :is='item.component' :params='item.params'/>
						<component v-else
								   :key='`n-tabs_n-tab-pane_component_else_${item.key}_component`'
								   :is='item.component'/>
					</template>
					<template v-slot:fallback>
						<Loading/>
					</template>
				</Suspense>
			</n-tab-pane>
		</template>
	</n-tabs>
	<n-dropdown v-bind='contextMenuConfig' :on-clickoutside='onClickOutSide' @select='handleSelect'/>
</template>
<script lang='ts' setup>
import { defineAsyncComponent, h, onBeforeUpdate, onMounted, reactive, ref, nextTick } from 'vue';
import { useCommonStore } from '@/config/pinia/common.store.ts';
import { useTabsStore } from '@/config/pinia/tabs.store.ts';
import type { CommonMenuProps } from '#/Menu.d.ts';
import { homeCode } from '@/config/pinia/menus.store.config.ts';
import { TabsProps, DropdownProps } from 'naive-ui';
const props = defineProps({
	showOption : {
		type    : Function,
		require : true
	}
});
const Loading = defineAsyncComponent(() => import('@/components/customComponents/loading/Loading11.vue'));
const SvgIcon = defineAsyncComponent(() => import('@/components/customComponents/icon/SvgIcon.vue'));
const ClassIcon = defineAsyncComponent(() => import('@/components/customComponents/icon/ClassIcon.vue'));
const commonStore = useCommonStore();
const tabsStore = useTabsStore();
const tabConfig = reactive<TabsProps>({
	animated         : true,
	type             : 'card',
	paneWrapperStyle : { height : '100%', width : '100%', margin : '0', padding : '0' },
	paneStyle        : { height : '100%', width : '100%', margin : '0', padding : '0' },
	onBeforeLeave    : (name: string | number, oldName: string | number | null) => switchTab(name, oldName),
	onClose          : (value: string | number) => removeTab(value)
});
const renderIcon = (iconType: string, iconClass: string): any => {
	return () => {
		// @ts-ignore
		return h(SvgIcon, {
			'icon-type'  : iconType,
			'icon-class' : iconClass
		});
	};
};
const contextMenuConfig: DropdownProps = reactive({
	show      : false,
	animated  : true,
	size      : 'large',
	placement : 'bottom-start',
	trigger   : 'manual',
	x         : 0,
	y         : 0,
	options   : [
		{ label : '刷新该页', key : 'refreshTarget', icon : renderIcon('customized', 'refresh/customized-refresh14') },
		{ label : '关闭其他', key : 'closeOther', icon : renderIcon('iconfont5', 'iconfont5-Close') },
		{ label : '关闭所有', key : 'closeAll', icon : renderIcon('iconfont5', 'iconfont5-Close') }
		/*{ label : '移除事件', key : 'removeEvent' }*/
	]
});
onMounted(() => {});
onBeforeUpdate(() => {});
const displayMode = (item: CommonMenuProps) => {
	// 此处使用懒加载优化
	// 懒加载优化可以让打开多个页面的人在刷新后快速回到之前打开的位置上
	// 而不是把所有打开但是没有切换到的Tabs页面一起加载出来
	switch (item.isCache) {
		case true:
			return 'show:lazy';
		case false:
			return 'if';
		default:
			return 'show:lazy';
	}
};
// 支持渲染svg图标
const renderLabel = (item: CommonMenuProps): any => {
	if (item.tabIconType) {
		if ('svg' === item.tabIconType) {
			let iconType;
			if (item.tabIcon?.match('fa-')) {
				iconType = 'fa';
			} else if (item.tabIcon?.match('iconfont5-')) {
				iconType = 'iconfont5';
			} else {
				iconType = 'customized';
			}
			return h('span', [
				// @ts-ignore
				h(SvgIcon, {
					'icon-type'  : iconType,
					'icon-class' : item.tabIcon
				}),
				' ',
				h('span', item.menuName)
			]);
		} else if ('class' === item.tabIconType) {
			return h('span', [
				// @ts-ignore
				h(ClassIcon, { 'icon-class' : item.tabIcon }),
				' ',
				h('span', item.menuName)
			]);
		}
	}
};
const switchTab = async (name: string | number, oldName: string | number | null): Promise<boolean> => {
	// 左侧菜单选中样式
	tabsStore.currentActivatedTab = name;
	// 左侧菜单展开
	// @ts-ignore
	props.showOption(/*tabsStore.currentActivatedTab*/);
	// tabsStore.changeCurrentActivateComponent(name).then(() => {
	await tabsStore.syncTabsToSession();
	// });
	// 返回false将会阻止标签的默认切换行为
	return false;
};
const removeTab = async (value: string | number): Promise<void> => {
	tabsStore.removeTab(value).then(() => {
		// @ts-ignore
		props.showOption(/*tabsStore.currentActivatedTab*/);
	});
};
const onRightClick = async (event: MouseEvent, item: CommonMenuProps) => {
	// 阻止默认事件
	event.preventDefault();
	// 阻止传播
	event.stopPropagation();
	// 阻止即时传播
	event.stopImmediatePropagation();
	// 设置当前选中项
	tabsStore.currentSelectedTab = item;
	// 根据event的X轴和Y轴设置菜单的位置
	Object.assign(contextMenuConfig, {
		show : true,
		x    : event.clientX,
		y    : event.clientY
	});
};
const onClickOutSide = async (event: MouseEvent) => {
	contextMenuConfig.show = false;
	tabsStore.currentSelectedTab = null;
};
const closeContextMenu = async () => {
	contextMenuConfig.show = false;
	tabsStore.currentSelectedTab = null;
};
const handleSelect = async (key: string | number) => {
	switch (key) {
		case 'refreshTarget':
			await refreshTarget();
			break;
		case 'closeOther':
			await closeOther();
			break;
		case 'closeAll':
			await closeAll();
			break;
	}
};
const refreshTarget = async (): Promise<void> => {
	// 刷新当前选择的tab
	const currentSelectedTab = tabsStore.currentSelectedTab;
	tabsStore.refreshTab(currentSelectedTab!.menuCode).then(() => {
		// 完成操作后将关闭右键菜单
		closeContextMenu();
	});
};
const closeOther = async (): Promise<void> => {
	tabsStore.removeOtherTabs().then((menuCode: string) => {
		// 完成操作后将关闭右键菜单
		closeContextMenu();
		// 将选择的标签页前置
		// 这里有一个响应式BUG
		// 当右键的目标标签页刚好是当前tabsStore.currentActivatedTab的值
		// 那么就算重新设置tabsStore.currentActivatedTab也不会切换回目标标签页
		// 这是由于相同值没有触发响应式所导致的
		// 所以下列将其设置成空字符串
		tabsStore.currentActivatedTab = '';
		// 然后在更新中触发响应式更新
		nextTick(() => {
			tabsStore.currentActivatedTab = menuCode;
		}).then(() => {
			// 一定要同步到sessionStorage
			tabsStore.syncTabsToSession();
			// @ts-ignore
			props!.showOption(tabsStore.currentActivatedTab);
		});

	}).catch(error => {
		console.error(error);
		// 即使出异常了也将关闭右键菜单
		closeContextMenu();
	});
};
const closeAll = async (): Promise<void> => {
	tabsStore.removeAllTabs().then((menuCode: string) => {
		// 完成操作后将关闭右键菜单
		closeContextMenu();
		// 将左侧菜单树的展开并选中项指向到首页
		// 将首页前置
		// 这里有一个响应式BUG
		// 当右键的目标标签页刚好是当前tabsStore.currentActivatedTab的值
		// 那么就算重新设置tabsStore.currentActivatedTab也不会切换回目标标签页
		// 这是由于相同值没有触发响应式所导致的
		// 所以下列将其设置成空字符串
		tabsStore.currentActivatedTab = '';
		// 然后在更新中触发响应式更新
		nextTick(() => {
			tabsStore.currentActivatedTab = menuCode;
		}).then(() => {
			// 一定要同步到sessionStorage
			tabsStore.syncTabsToSession();
			// @ts-ignore
			props!.showOption(menuCode);
		});
	}).catch(error => {
		console.error(error);
		// 即使出异常了也将关闭右键菜单
		closeContextMenu();
	});
};
</script>
<style lang='scss' scoped>
.tabs-container{
	margin  :0;
	padding :0;
	border  :0;
	height  :100%;
	width   :100%;
}
:deep(.n-tabs-pane-wrapper){
	height     :100%;
	width      :100%;
	position   :relative;
	overflow   :hidden;
	transition :max-height .2s var(--n-bezier);
}
</style>